package org.hepeng.workx.mybatis.executor;

import org.apache.commons.lang3.BooleanUtils;
import org.apache.ibatis.mapping.SqlCommandType;
import org.hepeng.workx.jdbc.DataSourceRoute;
import org.hepeng.workx.mybatis.sql.SQLStatementInfo;

import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author he peng
 */
public final class SQLExecuteContext extends ConcurrentHashMap<String, Object> {

    private SQLExecuteContext() {}

    private static final ThreadLocal<SQLExecuteContext> THREAD_LOCAL = new ThreadLocal<SQLExecuteContext>() {
        @Override
        protected SQLExecuteContext initialValue() {
            return new SQLExecuteContext();
        }
    };

    public static SQLExecuteContext getContext() {
        return THREAD_LOCAL.get();
    }

    public static void setContext(SQLExecuteContext context) {
        THREAD_LOCAL.set(context);
    }

    public static void close() {
        THREAD_LOCAL.remove();
    }

    public void set(String key , Object value) {
        if (Objects.nonNull(key) && Objects.nonNull(value)) {
            put(key , value);
        } else if (Objects.isNull(key)) {
            remove(key);
        }
    }

    public Object getObject(String key) {
        return get(key);
    }

    public DataSourceRoute getDataSourceRoute() {
        Object dataSourceRoute = get("dataSourceRoute");
        return Objects.nonNull(dataSourceRoute) ? (DataSourceRoute) dataSourceRoute : null;
    }

    public String getSql() {
        Object sql = get("sql");
        return Objects.nonNull(sql) ? sql.toString() : null;
    }

    public Boolean getFlushCacheRequired() {
        Object flushCacheRequired = get("flushCacheRequired");
        return Objects.nonNull(flushCacheRequired) ? BooleanUtils.toBoolean((Boolean) flushCacheRequired) : Boolean.FALSE;
    }

    public Object getArgs() {
        Object parameter = get("args");
        return Objects.nonNull(parameter) ? parameter : null;
    }

    public Object getResult() {
        Object result = get("result");
        return Objects.nonNull(result) ? result : null;
    }

    public SqlCommandType getSqlCommandType() {
        SqlCommandType sqlCommandType = (SqlCommandType) get("sqlCommandType");
        return Objects.nonNull(sqlCommandType) ? sqlCommandType : null;
    }

    public SQLStatementInfo getSqlStatementInfo() {
        Object result = get("sqlStatementInfo");
        return Objects.nonNull(result) ? (SQLStatementInfo) result : null;
    }

    public Class<?> getMapperInterface() {
        Object result = get("mapperInterface");
        return Objects.nonNull(result) ? (Class<?>) result : null;
    }
}
